using System;
using System.Collections.Generic;
using System.Text;

namespace Xivo.PCRComm
{
  public class RingBuffer
  {
    const int size = 16384;
    byte[] buffer = new byte[size];
    int readPos = 0;
    int writePos = 0;

    public bool isEmpty()
    {
      if (readPos == writePos)
        return true;
      else
        return false;
    }

    public int Count
    {
      get
      {
        int len = writePos - readPos;
        if (len < 0)
          len += size;
        return len;
      }
    }

    public void Clear()
    {
      writePos = 0;
      readPos = 0;
    }

    public byte this[int index]
    {
      get
      {
        return buffer[(readPos + index) % size];
      }
      set
      {
        buffer[(writePos + index) % size] = value;
      }
    }

    public void Write(byte data)
    {
      buffer[writePos] = data;
      writePos = (writePos + 1) % size;
      if (readPos == writePos)
        throw new Exception("Buffer full");
    }

    public byte Peek()
    {
      return buffer[readPos];
    }

    public byte Read()
    {
      int pos = readPos;
      readPos = (readPos + 1) % size;
      return buffer[pos];
    }

    public void Read(byte[] buffer, int offset, int len)
    {
      for (int i = 0; i < len; ++i)
        buffer[i] = Read();
    }

    public void Discard(int bytes)
    {
      if (Count < bytes)
        bytes = Count;

      readPos = (readPos + bytes) % size;
    }

    public string getString(int pos, int length)
    {
      string s = "";
      for (int i = pos; i < pos + length; ++i)
      {
        if (this[i] >= 32 && this[i] <= 127)
          s += (char)this[i];
      }
      return s.Trim();
    }


    public void displayBuffer(int Length)
    {
      int i = 0;
      while (i < Length)
      {
        System.Diagnostics.Debug.Write(i.ToString("X2") + " : ");
        for (int j = i; j < i + 16; ++j)
        {
          if (j < Length)
            System.Diagnostics.Debug.Write(this[j].ToString("X2"));
          else
            System.Diagnostics.Debug.Write("  ");
          System.Diagnostics.Debug.Write(' ');
        }
        System.Diagnostics.Debug.Write(": ");
        for (int j = i; j < i + 16; ++j)
        {
          char c;
          if (j < Length)
            c = (char)this[j];
          else
            c = ' ';
          if (c < ' ' || c > '~')
            c = '.';
          System.Diagnostics.Debug.Write(c);
        }
        i += 16;
        System.Diagnostics.Debug.WriteLine(" :");
      }
      System.Diagnostics.Debug.WriteLine("");
    }
  }
}
